package com.iqiao.platform.service.impl;

import com.iqiao.common.security.JwtTokenUtil;
import com.iqiao.common.security.JwtUser;
import com.iqiao.platform.dao.AdminDao;
import com.iqiao.platform.dao.UserDao;
import com.iqiao.platform.enums.PlatformType;
import com.iqiao.platform.model.Admin;
import com.iqiao.platform.model.User;
import com.iqiao.platform.service.AuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collection;

/**
 * Created by flt on 2017/10/31.
 */
@Service
public class AuthServiceImpl implements AuthService {


    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private AdminDao adminDao;

    @Override
    @Transactional
    public String login(String username, String password) {
        // Perform the security
        final Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(username, password)
        );
        SecurityContextHolder.getContext().setAuthentication(authentication);

        // Reload password post-security so we can generate token
        final JwtUser jwtUser = this.loadUserByUsername(username);
        return jwtTokenUtil.generateAccessToken(jwtUser);
    }

    @Override
    public String refresh(String token) {
        String username = jwtTokenUtil.getUsernameFromToken(token);
        JwtUser user = this.loadUserByUsername(username);

        if (jwtTokenUtil.canTokenBeRefreshed(token, user.getPasswordResetDate())) {
            return jwtTokenUtil.refreshToken(token);
        } else {
            return null;
        }
    }

    @Override
    @Transactional(readOnly = true)
    public JwtUser loadUserByUsername(String username) {
        Collection<? extends GrantedAuthority> authorities = new ArrayList<>();

        Admin admin = adminDao.findByUsername(username);
        if (null == admin) {
            throw new UsernameNotFoundException(String.format("admin not found by username: %s", username));
        }

        return new JwtUser(admin.getUserId(), username, admin.getPassword(), PlatformType.ADMIN, authorities);
    }
}
